package MyGui;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

import DistSys.*;
import Element.AbsElem;
import Element.Geom.AbsElemGeom;

public class FindDlg extends MyDlgFrame implements ActionListener, WindowListener{

    private JTextField   tfID, tfName, tfDesc;
    private ZoneComboBox comboZone;
    private JComboBox    comboType, comboTemplate;
    private JCheckBox    checkIsolated, checkNormOpen;
    private ElemListScrollPane scrollPane;
    private JButton      btnFindMatch, btnShowHide;
    private JButton      btnGoto, btnAddToSelection, btnSelect, btnPutInLog;

    /* Show/hide list */
    private int iIsShown = 0; // list is initially hidden
    private int[] aiHeight = new int[] { 64, 440 }; // initial heights
    private String[] asBtnText = new String[] { "Show Filter", "Hide Filter" };
    private Component[] aNextFocusComp = new Component[] { null, null };

    public FindDlg(MainFrame parent, String title) {
        super(parent, title);
        setSize(280, aiHeight[iIsShown]);
        setResizable(iIsShown != 0);
        setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);

        Container contentPane = getContentPane();
        contentPane.setLayout(new BorderLayout());

        contentPane.add(createTopPanel(), BorderLayout.NORTH);
        contentPane.add(createFilterPanel(), BorderLayout.CENTER);

        getRootPane().setDefaultButton(btnFindMatch);
        aNextFocusComp[0] = tfID;
        aNextFocusComp[1] = tfName;
        btnShowHide.setNextFocusableComponent(aNextFocusComp[iIsShown]);

        this.addWindowListener(this);
    }

    public JPanel createTopPanel(){
        JPanel p = new JPanel(gridBagLayout);

        tfID = new JTextField("",8);
        JLabel lblID = new JLabel("ID");
        lblID.setDisplayedMnemonic('I');
        lblID.setLabelFor(tfID);
        btnFindMatch = new JButton("Find");
        btnFindMatch.setMnemonic('F');
        btnFindMatch.addActionListener(this);
        btnShowHide = new JButton(asBtnText[iIsShown]);
        btnShowHide.setMnemonic('L');
        btnShowHide.addActionListener(this);

        GridBagConstraints c = new GridBagConstraints();
        c.insets = new Insets(GAP, GAP, GAP, 0);
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0; p.add(lblID, c);
        c.gridx = 1; c.weightx = 1; p.add(tfID, c);
        c.gridx = 2; c.weightx = 0; p.add(btnFindMatch, c);
        c.gridx = 3; c.insets.right = GAP; p.add(btnShowHide, c);

        return p;
    }

    public JPanel createFilterPanel(){
        JPanel p = new JPanel(gridBagLayout);
        GridBagConstraints c = new GridBagConstraints();

        tfName = new JTextField(6);
        JLabel lblName = new JLabel("Name", JLabel.RIGHT);
        lblName.setDisplayedMnemonic('N');
        lblName.setLabelFor(tfName);

        tfDesc = new JTextField(6);
        JLabel lblDesc = new JLabel("Desc.", JLabel.RIGHT);
        lblDesc.setDisplayedMnemonic('D');
        lblDesc.setLabelFor(tfDesc);

        comboZone = new ZoneComboBox();
        JLabel lblZone = new JLabel("Area", JLabel.RIGHT);
        lblZone.setDisplayedMnemonic('R');
        lblZone.setLabelFor(comboZone);

        comboType = new JComboBox(SysConst.ssType);
        JLabel lblType = new JLabel("Type", JLabel.RIGHT);
        lblType.setDisplayedMnemonic('T');
        lblType.setLabelFor(comboType);

        comboTemplate = new JComboBox(
            Templates.mapAllListToStringsWithAllNoneOptions());
        JLabel lblDefault = new JLabel("Templ.", JLabel.RIGHT);
        lblDefault.setDisplayedMnemonic('E');
        lblDefault.setLabelFor(comboTemplate);

        checkIsolated = new JCheckBox("Isolated");
        checkIsolated.setMnemonic('O');
        checkIsolated.setEnabled(false);
        checkIsolated.setVisible(false);
        checkNormOpen = new JCheckBox("Normally Open");
        checkNormOpen.setMnemonic('M');
        checkNormOpen.setEnabled(false);
        checkNormOpen.setVisible(false);

        scrollPane = new ElemListScrollPane(mainFrame,
            ElemListTableModel.PANE_FIND, JTable.AUTO_RESIZE_OFF);
        scrollPane.setPreferredSize(new Dimension(150, 150));

        btnGoto = new JButton("Goto");
        btnGoto.setMnemonic('G');
        btnGoto.addActionListener(this);
        btnAddToSelection = new JButton("Add to Selection");
        btnAddToSelection.setMnemonic('A');
        btnAddToSelection.addActionListener(this);
        btnSelect = new JButton("Select");
        btnSelect.setMnemonic('S');
        btnSelect.addActionListener(this);
        btnPutInLog = new JButton("Put In Log");
        btnPutInLog.setMnemonic('P');
        btnPutInLog.setEnabled(false);
        btnPutInLog.addActionListener(this);

        c.insets = new Insets(0, GAP, 0, 0);
        c.anchor = GridBagConstraints.WEST; //left alignment
        c.fill = GridBagConstraints.BOTH;

        c.gridy = 0; c.weightx = 0; c.gridwidth = 1;
        c.gridx = 0; c.insets.right = 0;   p.add(lblName, c);
        c.weightx = 1; c.gridwidth = GridBagConstraints.REMAINDER;
        c.gridx = 1; c.insets.right = GAP; p.add(tfName, c);

        c.gridy = 1; c.weightx = 0; c.gridwidth = 1;
        c.gridx = 0; c.insets.right = 0;   p.add(lblDesc, c);
        c.weightx = 1; c.gridwidth = GridBagConstraints.REMAINDER;
        c.gridx = 1; c.insets.right = GAP; p.add(tfDesc, c);

        c.gridy = 2; c.weightx = 0; c.gridwidth = 1;
        c.gridx = 0; c.insets.right = 0;   p.add(lblZone, c);
        c.weightx = 1; c.gridwidth = GridBagConstraints.REMAINDER;
        c.gridx = 1; c.insets.right = GAP; p.add(comboZone, c);

        c.gridy = 3; c.weightx = 0; c.gridwidth = 1;
        c.gridx = 0; c.insets.right = 0;   p.add(lblType, c);
        c.weightx = 1; c.gridwidth = GridBagConstraints.REMAINDER;
        c.gridx = 1; c.insets.right = GAP; p.add(comboType, c);

        c.gridy = 4; c.weightx = 0; c.gridwidth = 1;
        c.gridx = 0; c.insets.right = 0;   p.add(lblDefault, c);
        c.weightx = 1; c.gridwidth = GridBagConstraints.REMAINDER;
        c.gridx = 1; c.insets.right = GAP; p.add(comboTemplate, c);

        c.gridy = 5; c.gridwidth = 2;
        c.gridx = 0; p.add(checkIsolated, c);
        c.gridx = 2; p.add(checkNormOpen, c);

        c.gridy = 6; c.weighty = 1; c.gridwidth = GridBagConstraints.REMAINDER;
        c.gridx = 0; c.insets.bottom = GAP; p.add(scrollPane, c);

        c.gridy = 7; c.weighty = 0; c.gridwidth = 2;
        c.gridx = 0; c.insets.right = 0;   p.add(btnGoto, c);
        c.gridx = 2; c.insets.right = GAP; p.add(btnAddToSelection, c);
        c.gridy = 8;
        c.gridx = 0; c.insets.right = 0;   p.add(btnSelect, c);
        c.gridx = 2; c.insets.right = GAP; p.add(btnPutInLog, c);

        return p;
    }

    public void actionPerformed(ActionEvent evt) {
        Object src = evt.getSource();
        getRootPane().setDefaultButton( btnFindMatch );

        if (src == btnShowHide) {
            // Save old height
            Dimension d = getSize();
            aiHeight[iIsShown] = d.height;
            // Toggle iIsShown
            iIsShown = 1 - iIsShown;
            // Set new heights, button text and next focusable component
            setSize(d.width, aiHeight[iIsShown]);
            setResizable(iIsShown != 0);
            btnShowHide.setText(asBtnText[iIsShown]);
            btnShowHide.setNextFocusableComponent(aNextFocusComp[iIsShown]);
            // Validate layout
            validate();
            if (iIsShown != 0)
                tfID.setText("");
            else
                tfID.selectAll();
        } else if (src == btnFindMatch) {
            scrollPane.getData().removeAllElements();
            scrollPane.getModel().fireTableDataChanged();
            int iID = -1;
            if (tfID.getText().length() > 0) {
                try {
                    iID = Integer.parseInt(tfID.getText());
                    iID--; // User's version = developer's version + 1
                    if (iID >= Sys.elemList.size()) {
                        JOptionPane.showMessageDialog(this,
                            "ID out of range [1," + Sys.elemList.size() + "]");
                        return;
                    }
                } catch(NumberFormatException e) {
                    JOptionPane.showMessageDialog(this,
                        "Please input an integer!");
                } finally {
                    tfID.selectAll();
                }
            }
            if (iIsShown == 0) { // filter is hidden
                if (iID < 0) {
                    JOptionPane.showMessageDialog(this,
                        "Please input an integer!");
                } else {
                    Sys.clearSelectionAndFocus();
                    AbsElem elem = (AbsElem)Sys.elemList.elementAt(iID);
                    scrollPane.getData().add(elem);
                    Sys.addElemToSelection(elem);
                    mainFrame.mainPanel.centerForElem(elem);
                }
            } else { // filter is shown
                String name = tfName.getText();
                String desc = tfDesc.getText();
                double dZone;
                try {
                    dZone = comboZone.getSelectedZone();
                } catch(ZoneComboBox.ZoneException e) {
                    JOptionPane.showMessageDialog(mainFrame,
                        "'" + e.getMessage() + "' is not a valid zone.");
                    return;
                }
                int type = SysConst.mapIndexToType(comboType.getSelectedIndex());
                int idDftElem = comboTemplate.getSelectedIndex();
                if (type == SysConst.TYPE_NONE || idDftElem == 1) {
                    return;
                }
                AbsElem dftElem = null;
                if (idDftElem >= 2)
                    dftElem = (AbsElem)Templates.allList.elementAt(idDftElem-2);

                int index = 0;
                int iSize = Sys.elemList.size();
                if (iID >= 0) {
                    index = iID;
                    iSize = iID + 1;
                }
                for ( ; index < iSize; index++) {
                    AbsElem elem = (AbsElem)Sys.elemList.elementAt(index);
                    AbsElemGeom geom = elem.getElemGeomObj();
                    if (Zone.getZoneFits(dZone, elem) &&
                        (type == SysConst.TYPE_ALL || type == elem.getType()) &&
                        (dftElem == null || dftElem.equals(elem.getDftTemp()))&&
                        (name.length() == 0 || geom.getName().indexOf(name) >= 0) &&
                        (desc.length() == 0 || geom.getDesc().indexOf(desc) >= 0)) {
                        scrollPane.getData().add(elem);
                    }
                }
            }
            scrollPane.getModel().fireTableDataChanged();
        } else if (src == btnGoto) {         scrollPane.gotoSelectedElem(); }
        else if (src == btnAddToSelection) { scrollPane.addToSelection(); }
        else if (src == btnSelect) {         scrollPane.select(); }

    }

    /*======================================
      Implement WindowListener interfaces
    ======================================*/
    public void windowOpened( WindowEvent evt ){ }
    public void windowClosed( WindowEvent evt ){ }
    public void windowIconified( WindowEvent evt ){ }
    public void windowDeiconified( WindowEvent evt ){ }
    public void windowActivated( WindowEvent evt ){ scrollPane.updateTable(); }
    public void windowDeactivated( WindowEvent evt ){ }
    public void windowClosing( WindowEvent evt ){ }
}